import os
import uuid
from datetime import datetime
import oss2
from flask import current_app

class OssStorage:
    """
    阿里云OSS存储工具类
    用于处理文件上传到OSS对象存储
    """
    
    @staticmethod
    def init_oss_bucket():
        """初始化OSS连接"""
        auth = oss2.Auth(
            current_app.config['OSS_ACCESS_KEY_ID'],
            current_app.config['OSS_ACCESS_KEY_SECRET']
        )
        bucket = oss2.Bucket(
            auth,
            current_app.config['OSS_ENDPOINT'],
            current_app.config['OSS_BUCKET_NAME']
        )
        return bucket
    
    @staticmethod
    def generate_object_name(filename):
        """生成OSS对象名称，避免重名"""
        # 将文件名按日期和UUID组织，确保唯一性
        ext = os.path.splitext(filename)[1]
        date_prefix = datetime.now().strftime('%Y%m%d')
        unique_id = str(uuid.uuid4()).replace('-', '')
        return f"uploads/{date_prefix}/{unique_id}{ext}"
    
    @staticmethod
    def upload_file(file_storage):
        """
        上传文件到OSS
        :param file_storage: Flask的FileStorage对象
        :return: 文件的访问URL
        """
        if not current_app.config.get('USE_OSS_STORAGE', False):
            # 如果未启用OSS存储，使用本地存储
            filename = file_storage.filename
            file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
            file_storage.save(file_path)
            return f"/static/uploads/{filename}"
        
        try:
            # 初始化OSS连接
            bucket = OssStorage.init_oss_bucket()
            
            # 生成OSS对象名称
            object_name = OssStorage.generate_object_name(file_storage.filename)
            
            # 上传文件
            result = bucket.put_object(object_name, file_storage)
            
            if result.status == 200:
                # 上传成功，返回URL
                url_prefix = current_app.config['OSS_URL_PREFIX']
                return f"{url_prefix.rstrip('/')}/{object_name}"
            else:
                # 上传失败
                current_app.logger.error(f"OSS上传失败: {result.status}")
                return None
        except Exception as e:
            current_app.logger.error(f"OSS上传异常: {str(e)}")
            return None
    
    @staticmethod
    def delete_file(object_url):
        """
        从OSS删除文件
        :param object_url: 文件的完整URL
        :return: 是否删除成功
        """
        if not current_app.config.get('USE_OSS_STORAGE', False):
            # 如果是本地存储，获取文件路径
            if object_url.startswith('/static/uploads/'):
                filename = object_url.replace('/static/uploads/', '')
                file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
                if os.path.exists(file_path):
                    os.remove(file_path)
                return True
            return False
        
        try:
            # 从URL提取对象名称
            url_prefix = current_app.config['OSS_URL_PREFIX'].rstrip('/')
            if object_url.startswith(url_prefix):
                object_name = object_url.replace(url_prefix + '/', '')
                
                # 初始化OSS连接
                bucket = OssStorage.init_oss_bucket()
                
                # 删除对象
                result = bucket.delete_object(object_name)
                return result.status == 204  # 204表示删除成功
            return False
        except Exception as e:
            current_app.logger.error(f"OSS删除异常: {str(e)}")
            return False 